package com.lime49.lockcrypt;
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.print.*;
import javax.swing.*;
import java.text.SimpleDateFormat;
import java.text.MessageFormat;

public class Print implements Printable {
    private ResourceBundle lang;
    private ArrayList<String> linesAry;
    private String[] lines;
    int[] pageBreaks;  // array of page break line positions
    Font plainFont, boldFont, titleFont, footerFont;
    FontMetrics plainMetrics = null, titleMetrics, footerMetrics;
    int lineHeight, titleHeight, footerHeight;
    
    /**
    * Prints the specified list of accounts
    * @param accountsToPrint An ArrayList<Account> of accounts to print
    * @param lang The language ResourceBundle to use to label fields and pages
    */
    public Print(ArrayList<Account> accountsToPrint, ResourceBundle lang) {
        this.lang = lang;
        this.linesAry = new ArrayList<String>();
        for(Account acc : accountsToPrint) {
            linesAry.add("!!"+acc.getName());
            linesAry.add("!!"+lang.getString("TYPE")+": "+acc.getType());
            linesAry.add("!!"+lang.getString("GROUP")+": "+acc.getGroup());
            linesAry.add("!!"+lang.getString("CREATED")+": "+acc.getDateCreatedPretty(new SimpleDateFormat(lang.getString("DATEFORMAT"))));
            LinkedHashMap<String, String> fieldMap = acc.getTypeObject().getFieldMap();
            for(String fieldName : fieldMap.keySet()) {
                if(!fieldMap.get(fieldName).isEmpty()) {
                    linesAry.add("!!"+fieldName+": "+fieldMap.get(fieldName));
                }
            }
            linesAry.add("");
        }
        lines = new String[linesAry.size()];
        linesAry.toArray(lines);
        
        plainFont = new Font("SansSerif", Font.PLAIN, 10);
        boldFont = new Font("SansSerif", Font.BOLD, 10);
        titleFont = new Font("SansSerif", Font.BOLD, 14);
        footerFont = new Font("SansSerif", Font.PLAIN, 8);
    }
    
    /**
    * Calculates the dimensions for printing
    * @param g The graphics
    * @param pf The pageFormat
    * @param pageIndex The page number
    * @return
    */
    public int print(Graphics g, PageFormat pf, int pageIndex) throws PrinterException {
        if(plainMetrics == null) {
            plainMetrics = g.getFontMetrics(plainFont);
            titleMetrics = g.getFontMetrics(titleFont);
            footerMetrics = g.getFontMetrics(footerFont);
            lineHeight = plainMetrics.getHeight();
            titleHeight = titleMetrics.getHeight();
            footerHeight = footerMetrics.getHeight();
        }
        int linesPerPage = (int)((pf.getImageableHeight()-titleHeight-footerHeight)/lineHeight);
        int numBreaks = (lines.length-1)/linesPerPage;
        pageBreaks = new int[numBreaks];
        for(int b=0; b<numBreaks; b++) {
            pageBreaks[b] = (b+1)*linesPerPage; 
        }
        if(pageIndex > pageBreaks.length) {
            return NO_SUCH_PAGE;
        }
        Graphics2D g2d = (Graphics2D)g;
        g2d.translate(pf.getImageableX(), pf.getImageableY());
        
        int y = titleHeight; 
        
        g.setFont(titleFont);
        g.drawString("LockCrypt", (int)(pf.getImageableWidth()/2)-g.getFontMetrics().stringWidth("LockCrypt"), y);
        
        int start = (pageIndex == 0) ? 0 : pageBreaks[pageIndex-1];
        int end   = (pageIndex == pageBreaks.length)
                         ? lines.length : pageBreaks[pageIndex];
        for(int line=start; line<end; line++) {
            y += lineHeight;
            if(lines[line].startsWith("!!")) {
                g.setFont(boldFont);
                String[] parts = lines[line].substring(2).split(": ");
                g.drawString(parts[0], 0, y);
                if(parts.length>1) {
                    g.setFont(plainFont);
                    g.drawString(" : "+parts[1], g.getFontMetrics().stringWidth(parts[0]), y);
                }
            } else {
                g.setFont(plainFont);
                g.drawString(lines[line], 0, y);
            }
        }
        y = (int)pf.getImageableHeight()-footerHeight;
        MessageFormat format = new MessageFormat(lang.getString("PAGENUM"));
        String footerText = format.format(new Object[] {pageIndex+1, pageBreaks.length+1});
        g.drawString(footerText, (int)(pf.getImageableWidth()/2)-g.getFontMetrics().stringWidth(footerText), y);
        return PAGE_EXISTS;
    }
    
    /**
    * Creates a PrinterJob and shows a print dialog.
    */
    public void showDialog() {
        PrinterJob job = PrinterJob.getPrinterJob();
        job.setPrintable(this);
        boolean ok = job.printDialog();
        if(ok) {
            try {
                job.print();
            } catch (PrinterException ex) {
              /* The job did not successfully complete */
            }
        }
    }
}
